﻿using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Configuration;
using System.IO;

namespace DAL.SqlHelper
{
    public class SQLHelper
    {
        // 数据库信息
        private static readonly string connString = ConfigurationManager.ConnectionStrings["connString"].ToString();

        /// <summary>
        ///     执行查询结果集的操作
        /// </summary>
        /// <param name="sql"></param>
        /// <returns></returns>
        public static SqlDataReader GetReader(string sql)
        {
            // 创建connection对象建立数据连接
            SqlConnection conn = new SqlConnection(connString);

            // 创建command对象，封装sql语句与connection对象
            SqlCommand cmd = new SqlCommand(sql, conn);

            // 异常处理，预防异常发生
            try
            {
                // 打开数据连接
                conn.Open();

                // 执行增删改操作并返回受影响的行数
                SqlDataReader result = cmd.ExecuteReader(CommandBehavior.CloseConnection);
                return result;
            }
            catch (Exception ex)
            {
                // 将异常对象抛给方法的调用者处理
                throw ex;
            }
        }

        // 用于获取某一个数据的某一列，或者验证数据是否存在
        /// <summary>
        /// 执行单一结果的查询操作
        /// </summary>
        /// <param name="sql">sql语句</param>
        /// <returns>查询结果中的第一行的第一列</returns>
        public static object GetSingleValue(string sql)
        {
            // 创建链接对象
            SqlConnection connection = new SqlConnection(connString);
            // 创建数据库操作句柄
            SqlCommand sqlCommand = new SqlCommand(sql, connection);
            try
            {
                connection.Open();
                // 执行查询，并返回查询结果中的第一行的第
                // 一列，其他结果将被忽略
                object res = sqlCommand.ExecuteScalar();
                return res;
            }
            catch (Exception ex)
            {
                // 记录日志
                File.AppendAllText("sqlError.log", $"[{DateTime.Now}]\t SQL: {sql}\t Error: {ex.Message}\n");

                // 抛出错误
                throw ex;
            }
            finally
            {
                // 断开链接
                connection.Close();
            }
        }

        /// <summary>
        /// 执行多条数据的查询，返回一个数据集
        /// </summary>
        /// <param name="sql">执行的SQL</param>
        /// <returns>查询的结果</returns>
        public static DataSet GetDataSet(string sql)
        {
            SqlConnection conn = new SqlConnection(connString);
            SqlCommand cmd = new SqlCommand(sql, conn);
            try
            {
                conn.Open();
                // 创建SqlServer数据桥接器，并执行sql语句（相当于执行Sql）
                SqlDataAdapter adapter = new SqlDataAdapter(cmd);
                // 创建DataSet数据集用于存储数据
                DataSet dataset = new DataSet();
                // 将数据桥接器中查询到的内容填充到数据集中
                adapter.Fill(dataset);
                return dataset;
            }
            catch (Exception ex)
            {
                // 记录日志
                File.AppendAllText("sqlError.log", $"[{DateTime.Now}]\t SQL: {sql}\t Error: {ex.Message}\n");

                // 抛出错误
                throw ex;
            }
            finally
            {
                conn.Close();
            }
        }

        /// <summary>
        /// 执行增删改操作
        /// </summary>
        /// <param name="sql">要执行的SQL语句</param>
        /// <returns>返回受影响的行数</returns>
        public static int Update(string sql)
        {
            // 创建链接对象
            SqlConnection connection = new SqlConnection(connString);
            // 创建数据库操作句柄
            SqlCommand sqlCommand = new SqlCommand(sql, connection);
            try
            {   // 执行可能出错的代码
                // 开启链接
                connection.Open();
                // 以非查询的方式执行sql，返回受影响的行数
                int res = sqlCommand.ExecuteNonQuery();
                // 返回受影响的行数
                return res;
            }
            catch (Exception ex)
            {   // 出现错误时执行的代码

                // 记录日志
                File.AppendAllText("sqlError.log", $"[{DateTime.Now}]\t SQL: {sql}\t Error: {ex.Message}\n");
                // DELETE 语句与 REFERENCE 约束"FK_attendances_students"冲突。该冲突发生于数据库"studentManages"，表"dbo.attendances", column 'cardNo'。
                // 抛出错误
                throw ex;
            }
            finally
            {   // 代码执行完毕，不管是否报错都会执行这里的代码
                // 不管是否报错，都应该关闭链接
                connection.Close();
            }
        }
    }
}
